package com.yueyang.sojourn.server.service.sojourn.projectshare;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yueyang.sojourn.server.model.dto.EditProjectShareDto;
import com.yueyang.sojourn.server.model.enums.*;
import com.yueyang.sojourn.server.model.po.SojournMerchant;
import com.yueyang.sojourn.server.model.po.SojournProjectShare;
import com.yueyang.sojourn.server.model.po.SojournProjectShareLog;
import com.yueyang.sojourn.server.service.sojourn.merchant.SojournMerchantService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 项目分账服务
 * @author andy.yang
 * @version v1
 * @summary
 * @Copyright (c) 2019, yueyang Group All Rights Reserved.
 * @since 2020/3/17
 */
@Service
public class SojournProjectShareService {
    @Resource
    SojournProjectShareMapper sojournProjectShareMapper;
    @Autowired
    SojournProjectShareLogService shareLogService;
    @Autowired
    SojournMerchantService merchantService;

    @Transactional
    public int addOrUpdateOrDel(List<EditProjectShareDto> sharesDto,Long projectId,Long userId){
        Map<Long,SojournProjectShare> projectSharesOld = findMapByProjectId(projectId);
        //主商户
        SojournMerchant merchantPrime = merchantService.findByProjectId(projectId);
        //拼装
        List<SojournProjectShare> adds = new ArrayList<>();//新增
        Map<Long,SojournProjectShare> updates = new HashMap<>();//更新
        List<Long> dels = new ArrayList<>();//删除
        for(EditProjectShareDto dto : sharesDto){
            boolean isPrime = merchantPrime.getId().equals(dto.getReceiverId());
            if(dto.getId() != null){
                SojournProjectShare share = projectSharesOld.get(dto.getId());
                BeanUtils.copyProperties(dto,share);
                share.setProjectId(projectId);
                updates.put(dto.getId(),share);
            }else{
                SojournProjectShare share = new SojournProjectShare();
                BeanUtils.copyProperties(dto,share);
                share.setReceiverType(PayConstants.ThirdPayAccountTypeEnum.WX_MERCHANT.getCode());//暂时只支持商户todo
                share.setRelationType(PayConstants.ThirdPayAccountRelationTypeEnum.WX_PARTNER.getCode());//当前分账接收方与主商户之间的关系
                share.setPrime(isPrime);
                share.setCreator(userId);
                share.setProjectId(projectId);
                share.setThirdSynStatus(ProjectShareThirdSynStatusEnum.TO_SYN.getCode());
                adds.add(share);
            }
        }
        for(SojournProjectShare shareDto : projectSharesOld.values()){
            if (!updates.keySet().contains(shareDto.getId())){
                dels.add(shareDto.getId());
            }
        }

        int rs = 1;
        if(adds != null && !adds.isEmpty()) {
            rs = sojournProjectShareMapper.batchInsert(adds) * rs;
        }
        if(updates != null && !updates.isEmpty()) {
            rs = sojournProjectShareMapper.batchUpdate(new ArrayList(updates.values())) * rs;
        }
        if(dels != null && !dels.isEmpty()) {
            rs = sojournProjectShareMapper.batchDel(dels, userId) * rs;
        }

        //记录修改记录
        if(!projectSharesOld.isEmpty()){
            List<Long> merchantIds = new ArrayList<>();
            if(sharesDto != null){
                sharesDto.stream().forEach((dto) -> {
                    //如果商户
                    merchantIds.add(dto.getReceiverId());//todo 暂时只支付商户
                });
            }
            for(SojournProjectShare share :projectSharesOld.values()){
                if(!merchantIds.contains(share.getReceiverId())
                        //&& PayConstants.ThirdPayAccountTypeEnum.WX_MERCHANT.equals(share.getReceiverType())
                    ){
                    merchantIds.add(share.getReceiverId());
                }else{
                    //todo
                }
            }

            final Map<Long, SojournMerchant> merchantMap = new HashMap<>();
            if(!merchantIds.isEmpty()) {
                List<SojournMerchant>  merchants = merchantService.findByIds(merchantIds);
                merchants.stream().forEach((merchant) ->{
                    merchantMap.put(merchant.getId(),merchant);
                });
            }

            //拼装日志
            List<Map<String,Object>> beforeList = new ArrayList();
            if(projectSharesOld != null){
                projectSharesOld.values().stream().forEach((old) ->{
                    Map<String, Object> before = new LinkedHashMap<>();
                    before.put("merchantId",old.getReceiverId());
                    before.put("merchantName", merchantMap.get(old.getReceiverId()) == null ?
                            null : merchantMap.get(old.getReceiverId()).getName());
                    before.put("shareRatio", old.getShareRatio());
                    beforeList.add(before);
                });
            }
            List<Map<String,Object>> afterList = new ArrayList<>();
            if(sharesDto != null) {
                sharesDto.stream().forEach((dto) -> {
                    Map<String, Object> after = new LinkedHashMap<>();
                    after.put("merchantId",dto.getReceiverId());
                    after.put("merchantName", merchantMap.get(dto.getReceiverId()) == null ?
                            null : merchantMap.get(dto.getReceiverId()).getName());
                    after.put("shareRatio", dto.getShareRatio());
                    afterList.add(after);
                });
            }
            SojournProjectShareLog log  = new SojournProjectShareLog();
            log.setBeforeValue(JSONArray.toJSONString(beforeList));
            log.setAfterValue(JSONArray.toJSONString(afterList));
            log.setProjectId(projectId);
            log.setStatus(StatusEnum.VALID.getCode());
            log.setCreator(userId);
            shareLogService.add(log);
        }

        //同步设置微信中的分账配置
        return rs;
    }
    /**
     * 创建项目分账
     * @param projectShare
     * @return
     */
    private Long add(SojournProjectShare projectShare){
        projectShare.setStatus(StatusEnum.VALID.getCode());
        sojournProjectShareMapper.insert(projectShare);
        return projectShare.getId();
    }

    /**
     * 编辑项目分账
     * @param projectShare
     * @return
     */
    public int update(SojournProjectShare projectShare){
        return sojournProjectShareMapper.update(projectShare);
    }


    /**
     * 更新同步状态
     * @param synStatusEnum
     * @return
     */
    public int updateThirdSynStatus(Long id,ProjectShareThirdSynStatusEnum synStatusEnum){
        return sojournProjectShareMapper.updateThirdSynStatus(id,synStatusEnum.getCode());
    }

    /**
     * 删除
     * @param projectShareId
     * @param userId
     * @return
     */
    private int delete(Long projectShareId,Long userId){
        return sojournProjectShareMapper.delete(projectShareId,userId);
    }

    /**
     * @param projectId      项目id
     * @param status      状态
     * @param thirdSynStatus      同步状态
     * @param pageNo      页码
     * @param pageSize    页大小
     * @return
     * @author Andy.yang
     * @summary 订单分页查询
     * @version v1
     * @since 2020-02-19
     */
    public PageInfo<SojournProjectShare> findPage(Long projectId,Integer status,Integer thirdSynStatus,int pageNo, int pageSize) {
        PageInfo<SojournProjectShare> pageInfo = PageHelper.startPage(pageNo, pageSize)
                .doSelectPageInfo(() -> sojournProjectShareMapper.findBy(projectId,status,thirdSynStatus));
        return pageInfo;
    }

    /**
     * @param projectShareId      项目分账id
     * @return
     * @author Andy.yang
     * @summary 查询
     * @version v1
     * @since 2020-02-19
     */
    public SojournProjectShare findById(Long projectShareId) {
        return sojournProjectShareMapper.selectByPrimaryKey(projectShareId);
    }

    /**
     * @param projectId      项目id
     * @return
     * @author Andy.yang
     * @summary 查询
     * @version v1
     * @since 2020-02-19
     */
    public List<SojournProjectShare> findListByProjectId(Long projectId) {
        return sojournProjectShareMapper.findByProjectId(projectId);
    }


    /**
     * @param projectId      项目id
     * @return
     * @author Andy.yang
     * @summary 查询
     * @version v1
     * @since 2020-02-19
     */
    public Map<Long,SojournProjectShare> findMapByProjectId(Long projectId) {
        Map<Long,SojournProjectShare> rs = new LinkedHashMap<>();
        List<SojournProjectShare> shares = sojournProjectShareMapper.findByProjectId(projectId);
        if(shares == null || shares.isEmpty()){
            return rs;
        }
        shares.stream().forEach((share)->{ rs.put(share.getId(),share);});
        return rs;
    }
}
